﻿// <copyright file="UPnPDeviceDiscovery.cs" company="EffuEfface">
//      Copyright (c) Effu Efface Consulting  All rights reserved.
// </copyright>
// <author>Ryan R. Sites</author>

namespace TVersiPlay.Common
{
    using System;
    using System.Collections.Generic;    
    using System.Net;
    using OpenSource.UPnP;
    using OpenSource.Utilities;


    public class UPnPDeviceDiscovery
    {
        #region declarations

        private UPnPSmartControlPoint scp;
        private WeakEvent AddEvent = new WeakEvent();
        private WeakEvent RemoveEvent = new WeakEvent();

        #endregion //declarations

        #region constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="UPnPDeviceDiscovery"/> class.
        /// </summary>
        public UPnPDeviceDiscovery()
        {
        }

        #endregion //constructors

        #region properties
        #endregion //properties

        #region methods

        /// <summary>
        /// Starts this instance.
        /// </summary>
        public void Start()
        {
            scp = new UPnPSmartControlPoint(new UPnPSmartControlPoint.DeviceHandler(OnAddSink));
            //scp = new UPnPSmartControlPoint(new UPnPSmartControlPoint.DeviceHandler(OnAddSink), null, "urn:schemas-upnp-org:device:MediaServer:1");
            scp.OnRemovedDevice += new UPnPSmartControlPoint.DeviceHandler(OnRemoveSink);
        }

        /// <summary>
        /// Rescans network for Media Servers
        /// </summary>
        public void ReScan()
        {
            scp.Rescan();
        }

        /// <summary>
        /// Unicast search by IP Address.
        /// </summary>
        /// <param name="address">The address.</param>
        public void UnicastSearch(IPAddress address)
        {
            scp.UnicastSearch(address);
        }

        /// <summary>
        /// Forces the dispose of the UPnP device.
        /// </summary>
        /// <param name="dev">The dev.</param>
        public void ForceDisposeDevice(UPnPDevice dev)
        {
            if (dev.ParentDevice != null)
            {
                ForceDisposeDevice(dev.ParentDevice);
            }
            else
            {
                scp.ForceDisposeDevice(dev);
            }
        }

        /// <summary>
        /// Called when [add sink].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="d">The d.</param>
        private void OnAddSink(UPnPSmartControlPoint sender, UPnPDevice d)
        {
            AddEvent.Fire(this, d);
        }

        /// <summary>
        /// Called when [remove sink].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="d">The d.</param>
        private void OnRemoveSink(UPnPSmartControlPoint sender, UPnPDevice d)
        {
            RemoveEvent.Fire(this, d);
        }

        #endregion //methods

        #region events

        public delegate void DiscoveryHandler(UPnPDeviceDiscovery sender, UPnPDevice dev);

        /// <summary>
        /// Occurs when [on added device].
        /// </summary>
        public event DiscoveryHandler OnAddedDevice
        {
            add
            {
                AddEvent.Register(value);
            }
            remove
            {
                AddEvent.UnRegister(value);
            }
        }

        /// <summary>
        /// Occurs when [on removed device].
        /// </summary>
        public event DiscoveryHandler OnRemovedDevice
        {
            add
            {
                RemoveEvent.Register(value);
            }
            remove
            {
                RemoveEvent.UnRegister(value);
            }
        }

        #endregion //events
    }

}
